export interface SpotI {
	/** X位置 */
	X: number;
	/** Y位置 */
	Y: number;
};

const APow3B = (NumA: number, NumB: number) => NumA * Math.pow(NumB, 3);
const Pow2AB = (NumA: number, NumB: number) => Math.pow(NumA, 2) * NumB;

/**
 * 三阶贝塞尔曲线计算
 * @param PosA 点A
 * @param PosB 点B
 * @param DeDieFalla 精度
 * @returns 输入x位置，折半x两端范围，根据x位置返回y位置
 */
export default function ThreeBezier (PosA: SpotI, PosB: SpotI, DeDieFalla: number = .01) {
	return function (Length: number, Index: number): number {
		const AX = PosA.X * Length;
		const AY = PosA.Y * Length;
		const BX = PosB.X * Length;
		const BY = PosB.Y * Length;
		const Max3 = Math.pow(Length, 3);
		if (Index == 0) { return 0; }
		if (Index >= Length - 1) { return 1; }
		let min = 0;
		let max = Length;
		let mid = (max + min) / 2;
		let dif = Length - mid;
		const calc = (A: number, B: number) =>
			((A * Pow2AB(dif, mid) + B * Pow2AB(mid, dif)) * 3 + APow3B(Length, mid)) / Max3;
		while ((max - min) > DeDieFalla) {
			const value = calc(AX, BX);
			if (value > Index) {
				max = mid;
			} else if (value < Index) {
				min = mid;
			}
			else break;
			mid = (min + max) / 2;
			dif = Length - mid;
		}
		return calc(AY, BY) / Length;
	}
};
